開發 Android APP 的許多的開發方法,除了Compose UI 之外小弟知道的如下:
要建構一個大房子,根基是很重要的,所以我們今天就來了解 Compose 主題的運作操作
官網上是這麼解釋什麼是 Theme(主題)的
Android 上的樣式和主題可讓您區分應用程式設計的詳細資料與 UI 結構和行為,與網頁設計中的樣式表類似。
「樣式」是屬性的集合,可指定單一 View 的外觀。樣式可指定各種屬性,例如字型顏色、字型大小、背景顏色等。
「主題」是套用至整個應用程式、活動或檢視區塊階層 (而不只是個別檢視畫面) 的屬性的集合。套用主題時,應用程式或活動中的每個檢視畫面都會套用該主題的每一個屬性 (須已支援)。主題也可以將樣式套用至非檢視元素,例如狀態列和視窗背景。
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Exampleday3Theme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
Greeting("Android")
}
}
}
}
}
我們建立好一個 compose 的 project 之後,可以看到 Activity 的 onCreate() 裡面 setContent 中有一個預設的 Theme 叫做 Exampleday3Theme, 這個名稱是根據 Project 命名自動生成的,在 Android Studio 裏,滑鼠移動到 Exampleday3Theme 然後 cmd + B (我的系統是macOS) 可以見到 Exampleday3Theme 的原始碼:
@Composable
fun Exampleday3Theme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) {
val colors = if (darkTheme) {
DarkColorPalette
} else {
LightColorPalette
}
MaterialTheme(
colors = colors,
typography = Typography,
shapes = Shapes,
content = content
)
}
這段程式碼是一個 Composable Function,主要是定義了兩個 Colors,分別是深色模式和淺色模式的主題,有兩個參數,第一個主要是指定是否為深色模式,第二個是我們的 content layout 內容,根據是否為深色模式來決定要使用的 Colors,之後 Apply 到 MaterialTheme 裡面。 MaterialTheme 也是一個 Composable Function, 有 colors、typography、shapes 與 Content.
我們從 darkColors Cmd+B 跳進去看一下是一個 Colors 的類別,裡面的變數都是 Observable 的 State。
@Stable
class Colors(
primary: Color,
primaryVariant: Color,
secondary: Color,
secondaryVariant: Color,
background: Color,
surface: Color,
error: Color,
onPrimary: Color,
onSecondary: Color,
onBackground: Color,
onSurface: Color,
onError: Color,
isLight: Boolean
) {
var primary by mutableStateOf(primary, structuralEqualityPolicy())
internal set
var primaryVariant by mutableStateOf(primaryVariant, structuralEqualityPolicy())
internal set
var secondary by mutableStateOf(secondary, structuralEqualityPolicy())
internal set
...
而 Color 類別,是一個很單純放置顏色定義的類別,可以自己隨時客製顏色。
我們要使用設置好的顏色,只需要透過 MaterialTheme 來存取想要用的顏色屬性名稱就可以了,如下:
@Composable
fun Greeting(name: String) {
Text(
text = "Hello $name!",
color = MaterialTheme.colors.primary
)
}
而現在 primary 被 override 成 Theme.kt 裡面被定義為 Purple200 for dark mode 以及 Purple500 for light mode. 所以看到的 preview 畫面是:
!preview1
如果我們想要把 Primary 的color 定義為橘色,很簡單只要改 theme/Color.kt 裡面新增一個新顏色:
“val Orange = Color(0xFFFF9800)”:
package com.hakka1.ithelp.example.day2.ui.theme
import androidx.compose.ui.graphics.Color
val Orange = Color(0xFFFF9800)
val Purple200 = Color(0xFFBB86FC)
val Purple500 = Color(0xFF6200EE)
val Purple700 = Color(0xFF3700B3)
val Teal200 = Color(0xFF03DAC5)
並且把 Theme.kt 的primary 變數值改為 Orange,然後重新把 Preview 畫面重新整理(refresh)後,TextView 的字體顏色就變成你想要的樣子。
private val DarkColorPalette = darkColors(
primary = Orange,
primaryVariant = Purple700,
secondary = Teal200
)
private val LightColorPalette = lightColors(
primary = Orange,
primaryVariant = Purple700,
secondary = Teal200
/* Other default colors to override
background = Color.White,
surface = Color.White,
onPrimary = Color.White,
onSecondary = Color.Black,
onBackground = Color.Black,
onSurface = Color.Black,
*/
)
雖然我們這一篇還沒有提到 UI 元件的控制,但我覺得 Theme 在專案開發會搭配 UI 設計師的想法而需要被客製化,今天先淺淺的瞭解一下 Theme 的觀念,未來有機會再來深入探討一番!
今天是中秋連假的第一天,祝大家月圓人團圓,佳節愉快。